iT邦幫忙

2026 iThome 鐵人賽

DAY 18
0
AI 自動化

30 天 AI 自動化實戰:用 n8n、FastAPI 與 Gemini 打造 AI 知識管家系列 第 18 篇

Day 18|Map-Reduce Summarization:把大型 AI 任務拆開來做

  • 分享至 

  • xImage
  •  

我們解決了超長文本無法一次塞入模型的問題,透過 Paragraph-aware Chunking 與 n8n 的 Loop 節點,成功將長文切塊並逐一獲得了多份「局部摘要」。但是,當一篇文章被切成 5 塊,我們就會得到 5 份獨立的 JSON 摘要。這些摘要之間可能有重複的概念,也缺乏全域的連貫性。在一個完整的 AI 知識管家中,我們最終需要的是「單一」且「結構化」的完整筆記,以便在 Phase 5 自動寫入 Notion 資料庫。我們該如何將這些破碎的局部知識,重新揉合成一篇完整的總結?

核心概念:Map-Reduce
為了解決這個問題,我們引入了分散式系統中常見的 Map-Reduce 概念:

  1. Map:這是我們在 Day 17 做的事。將巨大的原始資料切割成多個 Chunks,並讓 AI 對每個區塊獨立執行任務。
  2. Reduce:這就是今天的重點。將所有 Map 階段產生的局部結果收集起來,再次交由 AI 進行整合與去蕪存菁,最終產出一份全域的結構化結果。

透過這種「先拆解、再組合」的策略,我們能在不觸發 Token 上限、不發生 Attention 丟失的前提下,完美處理任何長度的輸入。

它在完整架構中的位置
https://ithelp.ithome.com.tw/upload/images/20260925/20183341Vo8yYpKAKO.png

我們需要建立一個 /reduce-summary 的端點。這個端點的任務不再是閱讀原始長文,而是閱讀「多份摘要的集合」,所以我需要在 FastAPI 新增以下內容

class ReduceRequest(BaseModel):
    aggregated_text: str

@app.post("/reduce-summary")
def reduce_summary(data: ReduceRequest):
    try:
        prompt = f\"\"\"
        你是一個專業的知識管家。以下是從一篇長篇文件(如論文或長文)中分段萃取出來的多份局部摘要(以 JSON 陣列形式呈現)。
        請將這些局部摘要重新組織,消除重複提及的概念,並融合成一篇語意連貫的最終總結。
        
        局部摘要總集:
        {data.aggregated_text}
        \"\"\"
        
        # 強制套用 Structured Output
        response = model.generate_content(
            prompt,
            generation_config=genai.GenerationConfig(
                response_mime_type="application/json",
                response_schema=ArticleSummary, 
            )
        )
        
        ai_result = json.loads(response.text)
        
        return {
            "status": "success",
            "data": ai_result
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

n8n 實作:匯整與呼叫

回到 n8n Workflow,我們要處理 Loop 節點跑完後的資料:

1. 聚合資料 (Aggregate Node)
接在 Loop 節點的 Done 分支後方。

  • Operation:選擇 Aggregate(或 Combine)。
  • Fields To Aggregate:設定為 data(這是你上一關 /summarize 回傳摘要所在的欄位名稱)。關閉 Rename Field。
  • 這一步會將所有局部摘要打包成一個名為 data 的大型陣列。

2. 呼叫 Reduce API (HTTP Request Node)
接在 Aggregate 節點後方。

  • Method:POST
  • URL:http://host.docker.internal:8000/reduce-summary
  • Body Content Type:JSON
  • Body Parameters:
    • Name:aggregated_text
    • Value:{{ JSON.stringify($json.data) }}
  • 技術細節:因為 FastAPI 端點預期接收純字串(String),所以我們必須使用 JSON.stringify 將 data 陣列轉換為 JSON 格式的文字字串,這樣 AI 才能正確讀取結構化的內容。

技術細節:因為 FastAPI 端點預期接收純字串,所以我們必須使用 JSON.stringify 將 data 陣列轉換為 JSON 格式的文字字串,這樣 AI 才能正確讀取結構化的內容。
https://ithelp.ithome.com.tw/upload/images/20260925/20183341ZmL2jDRVfQ.png

把複雜的問題拆分成獨立的子任務,再將結果匯總,這種運算思維是突破現有模型物理限制(如 Context Window 與 Rate Limit)最有效的方法。這套架構不只適用於摘要,未來若要做整本電子書的分析或超大型 Log 檔的稽核,都能沿用這套 Map-Reduce 管線。


上一篇
Day 17|Long Context 不代表可以全部塞進去:Chunking 的必要性
下一篇
Day 19|Prompt Engineering:其實是在定義 AI Node 的工作規格
系列文
30 天 AI 自動化實戰:用 n8n、FastAPI 與 Gemini 打造 AI 知識管家 共 24 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言